	
	import java.io.BufferedReader;
	import java.io.IOException;
	import java.io.InputStreamReader;

	import java.net.DatagramPacket;
	import java.net.InetAddress;
	import java.net.MalformedURLException;
	import java.net.MulticastSocket;
	import java.net.ServerSocket;
	import java.net.Socket;

	import java.rmi.RemoteException;

	import java.rmi.server.UnicastRemoteObject;
	import java.util.LinkedList;
	import javax.jmdns.JmDNS;
	import javax.jmdns.ServiceInfo;
	import javax.swing.JOptionPane;


	public class Temp_Machine extends UnicastRemoteObject implements machine, Runnable {
		/* This is Kevs bit no laughing at my code :( */

		private static final String SERVICE_TYPE = "smart_hospital._tcp.local.";
		private static final String SERVICE_NAME = "BloodPressure";
		private static final int SERVICE_PORT = 1268;

		private String serverHost;
		private int serverPort;
		private boolean foundserv=false;
		private String  SERVICENAME="hospitalserver";
		
		
		private JmDNS jmdns;
		LinkedList<String> recentPatients;
		boolean UDPin;
		String UDPMultiAdd;
		int UDPMultiPort;

		private String patientWard;//where patient is
		private String myLocation;// where machine is
		private String patientID;
		
		private Socket toServer;
		String temp_Result;
		protected MulticastSocket socket;
		protected InetAddress multicastAddress;
		private DoctorDisplay dd;

		
		//Constructer for starting the machine,(Broadcasting)
		public Temp_Machine(String location, String add, int multiPort) throws RemoteException, MalformedURLException{
			try {
				dd = new DoctorDisplay();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			UDPMultiAdd = add;
			UDPMultiPort = multiPort;
			myLocation = location;
			UDPin = true;
			temp_Result = null;
			patientID =null;
			socket = null;
			recentPatients = new LinkedList<String>();
			patientWard = null;
			foundserv = false;
			SERVICENAME = "hospitalserver";
			
		
		}

		public void UDPReceiver(String multicastGroup, int multiCastPort) {
			try {
				multicastAddress = InetAddress.getByName(multicastGroup);
				}
				catch(Throwable t) {
					System.out.println("Exception getting inetaddress for group:"+ multicastGroup);
				}
			try {
				// creates the multicast socket
				socket = new MulticastSocket(multiCastPort); 
				socket.joinGroup(multicastAddress);	 
				}
				catch (java.net.SocketException e) {
					System.out.println("Exception creating multicast socket and joining group: " + e.getMessage());
				}
			catch (IOException e) {     	 
				e.printStackTrace();		
			}
			// Keep reading forever
			while (UDPin == true) {
				try {
					byte[] buf = new byte[1024];
					DatagramPacket packet = new DatagramPacket(buf, buf.length);
					socket.receive(packet);
					String input = new String(packet.getData()).trim();
					String[] temp = input.split("_");
					this.patientID = temp[0];
					this.patientWard = temp[1];
					
					// break. Start broadcasting
					if (myLocation.equals(patientWard) && !recentPatients.contains(patientID)) {
						System.out.println("Patient " + patientID + " In myLocation :" + patientWard);
						UDPin = false;
						startBroadcasting();
						socket.close();
					}else if (recentPatients.contains(patientID)){
						System.out.println("Patient " + patientID + " Has already been seen");
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			}
			
		}

		
		public void completeTask(String patientID) {
			
			int result = 35 + (int) (Math.random() * ((39 - 35) + 1));
			this.temp_Result = Integer.toString(result);
			System.out.println("Results Called");
			sendServer(patientID);
			
		}
		
		public void sendServer(String patientID){
			try {
				String reply = dd.sendMessageFromGui("<?xml version=\"1.0\"?>\n" +
			"<patient_measurement>\n"+
			"<patient_id>"+patientID+"</patient_id>\n"+
			"<blood_pressure>"+temp_Result+"</blood_pressure>\n"+	
			"<ward>"+patientWard+"</ward>\n"+
			"</patient_measurement>\n"+
			"<xml_end>MessageEnd</xml_end>");
				recentPatients.add(patientID);
			
				System.out.println(reply);
				if(!reply.contains("OK")){
					JOptionPane.showMessageDialog(null, "Error sending message to sever, ");
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}

		public String getResults() {
			return temp_Result;

		}

		public void startBroadcasting() {
			JmDNS jmdns;
			try {
				jmdns = JmDNS.create();
				ServiceInfo info = ServiceInfo.create(SERVICE_TYPE, SERVICE_NAME,SERVICE_PORT, 0, 0, ""+patientID);
				jmdns.registerService(info);
				recentPatients.add(patientID);
				ServerSocket server = new ServerSocket(SERVICE_PORT, 5);
				boolean inUse = true;
			      while (inUse) {
			             Socket socket = server.accept();
			             BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			             String patient = in.readLine();
			             if(patient.equals(patientID)){
			            	 completeTask(patientID);
			             }
			             in.close();
			             socket.close();
			             unReg(jmdns, info);
			             inUse = false;
			       }
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				System.out.println("Machine Server failed: " + e);
			}
			UDPin = true;
			UDPReceiver(UDPMultiAdd, UDPMultiPort);
		}
		
		public void unReg(JmDNS jmdns, ServiceInfo info) {
			jmdns.unregisterService(info);	
		}
		
		public void run(){
			UDPReceiver(UDPMultiAdd, UDPMultiPort);
		}
		
		public static void main(String[] args) throws IOException {
			// UDP Receiver stuff
			System.out.println("Awating Patient");
			Temp_Machine machine = new Temp_Machine("Ward 3","230.0.0.1", 4445);
			Thread k = new Thread(machine);
			k.start();
			}

		}
	